package com.sugar.queryinfo.module.business.service.tffinance;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.idev.excel.EasyExcel;
import cn.idev.excel.context.AnalysisContext;
import cn.idev.excel.read.listener.ReadListener;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.sugar.queryinfo.module.business.util.HideUtil;
import com.sugar.queryinfo.module.infra.controller.admin.file.vo.file.FileUploadReqVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import com.sugar.queryinfo.module.business.controller.admin.tffinance.vo.*;
import com.sugar.queryinfo.module.business.dal.dataobject.tffinance.TfFinanceDO;
import com.sugar.queryinfo.framework.common.pojo.PageResult;
import com.sugar.queryinfo.framework.common.pojo.PageParam;
import com.sugar.queryinfo.framework.common.util.object.BeanUtils;

import com.sugar.queryinfo.module.business.dal.mysql.tffinance.TfFinanceMapper;

import static com.sugar.queryinfo.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.sugar.queryinfo.framework.common.util.collection.CollectionUtils.convertList;
import static com.sugar.queryinfo.framework.common.util.collection.CollectionUtils.diffList;
import static com.sugar.queryinfo.module.business.enums.ErrorCodeConstants.*;

/**
 * 真假财务 Service 实现类
 *
 * @author Ysugar
 */
@Slf4j
@Service
@Validated
public class TfFinanceServiceImpl implements TfFinanceService {

    @Resource
    private TfFinanceMapper tfFinanceMapper;

    @Override
    public Long createTfFinance(TfFinanceSaveReqVO createReqVO) {
        // 插入
        TfFinanceDO tfFinance = BeanUtils.toBean(createReqVO, TfFinanceDO.class);
        if (tfFinance.getRecordTime() == null)
            tfFinance.setRecordTime(LocalDateTime.now());
        tfFinanceMapper.insert(tfFinance);

        // 返回
        return tfFinance.getId();
    }

    @Override
    public void updateTfFinance(TfFinanceSaveReqVO updateReqVO) {
        // 校验存在
        validateTfFinanceExists(updateReqVO.getId());
        // 更新
        TfFinanceDO updateObj = BeanUtils.toBean(updateReqVO, TfFinanceDO.class);
        tfFinanceMapper.updateById(updateObj);
    }

    @Override
    public void deleteTfFinance(Long id) {
        // 校验存在
        validateTfFinanceExists(id);
        // 删除
        tfFinanceMapper.deleteById(id);
    }

    @Override
        public void deleteTfFinanceListByIds(List<Long> ids) {
        // 删除
        tfFinanceMapper.deleteByIds(ids);
        }


    private void validateTfFinanceExists(Long id) {
        if (tfFinanceMapper.selectById(id) == null) {
            throw exception(TF_FINANCE_NOT_EXISTS);
        }
    }

    @Override
    public TfFinanceDO getTfFinance(Long id) {
        return tfFinanceMapper.selectById(id);
    }

    @Override
    public PageResult<TfFinanceDO> getTfFinancePage(TfFinancePageReqVO pageReqVO) {
        pageReqVO.setName(pageReqVO.getName().trim());
        List<String> names = Arrays.stream(pageReqVO.getName().split(","))
                .filter(StrUtil::isNotBlank)
                .collect(Collectors.toList());

        LocalDateTime now = LocalDateTime.now();
        Integer riskType = pageReqVO.getRiskType();

        for (String name : names) {
            // 查询是否存在
            Long count = tfFinanceMapper.selectCount(Wrappers.<TfFinanceDO>lambdaQuery()
                    .eq(TfFinanceDO::getName, name)
                    .eq(Objects.nonNull(riskType), TfFinanceDO::getRiskType, riskType));

            // 若无，则查询 未收录是否有
            if (count <= 0) {
                riskType = 0;
                count = tfFinanceMapper.selectCount(Wrappers.<TfFinanceDO>lambdaQuery()
                        .eq(TfFinanceDO::getName, name)
                        .eq(TfFinanceDO::getRiskType, riskType));
            }

            if (count <= 0)
                tfFinanceMapper.insert(new TfFinanceDO().setName(name).setRecordTime(now)); // 若无，则插入一条
            else
                tfFinanceMapper.updateQueryCount(name, riskType); // 更新查询次数
        }

        PageResult<TfFinanceDO> pageResult = tfFinanceMapper.selectPage(pageReqVO);
        if (pageResult.getTotal() == 0){
            pageReqVO.setRiskType(0);
            return tfFinanceMapper.selectPage(pageReqVO);
        }

        return pageResult;
    }

    @Override
    public List<TfFinanceRespVO> getTfFinancesByIds(List<Long> ids) {
        return BeanUtils.toBean(tfFinanceMapper.selectByIds(ids), TfFinanceRespVO.class/*, respVO ->
                respVO.setName(HideUtil.name(respVO.getName()))
                        .setIdCard(HideUtil.idCard(respVO.getIdCard()))
                        .setMobile(HideUtil.mobile(respVO.getMobile()))*/);
    }

    @Override
    public void importExcel(FileUploadReqVO uploadReqVO) {
        final int[] i = {2};
        LocalDateTime now = LocalDateTime.now();

        try {
            EasyExcel.read(uploadReqVO.getFile().getInputStream(), new ReadListener<Map<Integer, String>>() {
                @Override
                public void invoke(Map<Integer, String> data, AnalysisContext context) {
                    try {
                        String idCard = data.get(2);
                        if (StrUtil.isNotBlank(idCard)){
                            Long count = tfFinanceMapper.selectCount(TfFinanceDO::getIdCard, idCard);
                            if (count > 0){
                                i[0] = i[0] + 1;
                                return;
                            }
                        }

                        String name = data.get(0);

                        TfFinanceDO tfFinanceDO = new TfFinanceDO();
                        tfFinanceDO.setName(name);
                        tfFinanceDO.setMobile(data.get(1));
                        tfFinanceDO.setIdCard(idCard);
                        String type = data.get(3);
                        if ("撸子".equals(type)){
                            tfFinanceDO.setType("撸子");
                            tfFinanceDO.setRiskType(2);
                        }else if ("真实财务".equals(type)){
                            tfFinanceDO.setType("安全客户");
                            tfFinanceDO.setRiskType(1);
                        }else {
                            tfFinanceDO.setType("未收录");
                            tfFinanceDO.setRiskType(0);
                        }
                        tfFinanceDO.setRemark(data.get(4));

                        tfFinanceDO.setRecordTime(now);
                                    // 插入
                        tfFinanceMapper.insert(tfFinanceDO);
                        i[0] = i[0] + 1;
                    }catch (Throwable e){
                        log.error("导入真假财务数据失败：", e);
                        throw exception(SERVER_BUSY);
                    }
                }

                // 读取完毕
                @Override
                public void doAfterAllAnalysed(AnalysisContext context) {
                }
            }).sheet().doRead();
        }catch (Throwable e){
            throw exception(IMPORT_EXCEL_ERROR, i[0]);
        }
    }

}